## 第06课 红外接收原理及应用


### （1）项目介绍：

![](media/image1.jpg)

红外遥控在日常生活中随处可见，它被用来控制各种家电，如电视、音响、录影机和卫星信号接收器。红外遥控是由红外发射和红外接收系统组成的，也就是一个红外遥控器和红外接收模块和一个能解码的单片机组成的。 

红外发射的遥控器发射的38K红外载波信号是由遥控器里的编码芯片对其进行编码。它是以一段引导码，用户码，数据码，数据反码组成，利用脉冲的时间间隔来区别是0还是1信号(高电平低电平之比约为1:1时被认为是信号0)，而编码就是由这些0 、1信号组成。同一个遥控器的用户码是不变的，用数据吗不同来分辨遥控器按的键不同。当按下遥控器按键时，遥控器发送出红外载波信号，红外接收器接收到信号时程序对载波信号进行解码，通过数据码的不同来判断按下的是哪个键。单片机由接收到的01信号进行解码，由此判断遥控器按下的是什么键。

![](media/image2.png)

红外接收我们用的是一个红外接收模块，主要由红外接收头组成，它是集接收、放大、解调一体的器件，它内部IC就已经完成了解调，能够完成从红外线接收到输出与TTL电平信号兼容的所有工作，输出的就是数字信号。他适用于红外线遥控和红外线数据传输。接收器做成的红外接收模块只有三个引脚，信号线，VCC，GND。与arduino和其他单片机连接通信非常方便。

### （2）红外接收的参数：

工作电压：3.3-5V（DC）

![](media/image3.png)

![](media/image4.png)

接口：3PIN接口

输出信号：数字信号

接收角度：90度

频率：38khz

接收距离：10米

**右图为红外接收模块的实物图和电路图**

### （3）项目组件：

| keyes PLUS 开发板*1 | Keyes brick L298P 电机驱动扩展板 V1*1 | keyes 草帽LED白发红模块*1 | keyes brick 红外接收传感器*1 | JMP-1 17键红外遥控*1 |
| --- | --- | --- | --- | --- |
| <img src="media/image5.png" width="200"> | <img src="media/image6.png" width="200"> | <img src="media/image7.png" width="200"> | <img src="media/image8.png" width="200"> | <img src="media/image9.png" width="200"> |
| USB线*1 | 3Pin 双母头杜邦线*1 | XH2.54-3Pin+杜邦母单*1 | 18650双节电池盒*1 | 18650电池*2 （电池自配） |
| <img src="media/image10.png" width="200"> | <img src="media/image11.jpg" width="200"> | <img src="media/image12.png" width="200"> | <img src="media/image13.png" width="200"> | <img src="media/image14.png" width="200"> |

### （4）接线图：

接线注意：由于红外接收传感器输入的数字信号，将红外接收传感器模块的“-”、“+”和S引脚分别用导线连接到keyestudio传感器扩展板G（GND）、V（VCC）、A1，模拟口在数字口不够的情况下，模拟口也可以当数字口使用，模拟口A0相当于数字口14，A1相当于数字口15，以此类推。

![](media/image15.png)

### （5）项目代码：

在编写代码之前，要先导入红外的库文件，具体步骤请参考，（如何导入arduino库文件）这个文档。

**示例代码 1（KE0165_6.1.ino）：**

```cpp
/*
  keyes 4WD 多功能智能车
  课程 6.1
  红外遥控
  http://www.keyes-robot.com
*/
#include <IRremote.h>  // 红外遥控库声明

const int RECV_PIN = A1;  // 红外接收器引脚

IRrecv irrecv(RECV_PIN);
decode_results results;

/* 功能：初始化串口和红外接收器 */
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();  // 启动红外接收器
}

/* 功能：循环检测红外信号并输出 */
void loop() {
  if (irrecv.decode(&results)) {  // 解码成功，收到红外信号
    Serial.println(results.value, HEX);  // 以16进制格式输出接收代码
    irrecv.resume();  // 准备接收下一个信号
  }
  delay(100);  // 延时100毫秒
}
```


### （6）项目结果：

上传好测试代码，打开串口监视器，设置波特率为9600，拿出遥控器，对准红外接收传感器发送信号，即可看相应按键的键值，如果按键时间过长，容易出现乱码。

![](media/image16.png)

我们通过测试得出的数值，做了一个遥控器按键值表，方便以后使用。

![](media/image17.png)

### （7）代码说明：

**irrecv.enableIRIn()-**启动红外解码后，这时候IRrecv对象会在后台接收红外线信号。

**decode()-**接着就可以利用decode()函数持续检查，看看有没有解码成功。

**irrecv.decode(&results)** 解码成功，这个函数会返回true，并把结果放在results里面，在解码一个红外线信号之后，要运行resume()函数，这样才会持续接收下一组信号。

### （8）项目拓展：

我们刚刚解码了红外遥控器的按键值，那我们能不能用测出的按键值来做一些控制呢，如果控制一个LED灯的亮和灭。我们来试一下，在9脚接上一个LED灯模块。红外接收器的脚位不变,当有遥控器的按键按下时,接在数字引脚9上的发光LED就会点亮，再按一下按键，led熄灭，接线图如下：

![](media/image18.png)



**示例代码 2（KE0165_6.2.ino）：**

```cpp
/*
  keyes 4WD 多功能智能车
  课程 6.2
  红外遥控
  http://www.keyes-robot.com
*/
#include <IRremote.h>

#define RECV_PIN A1    // 红外接收器引脚
#define LED_PIN 9      // 发光LED引脚

int ledState = 0;     // LED 状态变量，0 关闭，1 打开

IRrecv irrecv(RECV_PIN);
decode_results results;

/* 功能：初始化串口、红外接收器和LED引脚 */
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();           // 初始化红外接收器
  pinMode(LED_PIN, OUTPUT);      // 设置LED引脚为输出模式
}

/* 功能：检测红外信号，控制LED开关 */
void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);  // 输出接收到的红外码（十六进制）
    if (results.value == 0xFF02FD && ledState == 0) {  // 按下OK键且LED关闭
      digitalWrite(LED_PIN, HIGH);       // 点亮LED
      ledState = 1;                      // 更新状态为打开
    } else if (results.value == 0xFF02FD && ledState == 1) {  // 再次按下OK键且LED打开
      digitalWrite(LED_PIN, LOW);        // 熄灭LED
      ledState = 0;                      // 更新状态为关闭
    }
    irrecv.resume();                     // 准备接收下一个信号
  }
}
```

上传代码带开发板,当遥控器按下OK按键时,LED就会亮，再按一下LED就会灭,同时电脑的串口会出现按键的命令编码.
